package com.wujunshen.dumpling.core.query;

import com.wujunshen.dumpling.database.query.DataBaseQuery;
import com.wujunshen.dumpling.database.query.DataBaseType;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap;

import static com.wujunshen.dumpling.common.constant.Constants.MYSQL;

/**
 * The type Data base query factory.
 *
 * @author frank woo(吴峻申) <br>
 *     email:<a href="mailto:frank_wjs@hotmail.com">frank_wjs@hotmail.com</a> <br>
 * @date 2020 /9/4 10:34<br>
 */
@Slf4j
@AllArgsConstructor
public class DataBaseQueryFactory {
  private static final Map<DataBaseType, DataBaseQuery> DATABASE_QUERY = new ConcurrentHashMap<>();

  static {
    Iterable<DataBaseQuery> databaseQueries = ServiceLoader.load(DataBaseQuery.class);
    for (DataBaseQuery current : databaseQueries) {
      DATABASE_QUERY.put(current.getDataBaseType(), current);
    }
  }

  /** DataSource */
  @Getter private final DataSource dataSource;

  /**
   * @param jdbcUrl 数据库URL
   * @return DataBaseType
   */
  public static DataBaseType getDbType(String jdbcUrl) {
    if (jdbcUrl.contains(MYSQL)) {
      return DataBaseType.MYSQL;
    }
    return DataBaseType.DEFAULT;
  }

  /**
   * New query instance data base query.
   *
   * @return the data base query
   */
  public DataBaseQuery newInstance() {
    DataBaseQuery query = null;
    try (Connection connection = this.dataSource.getConnection()) {
      // 获取数据库URL 用于判断数据库类型
      String url = connection.getMetaData().getURL();

      query = DATABASE_QUERY.get(getDbType(url));
      query.setDataSource(this.dataSource);
    } catch (SQLException e) {
      log.error("exception message is:{}", ExceptionUtils.getStackTrace(e));
    }
    return query;
  }
}
